package com.hulk.dryad.admin.filter;

import com.fujieid.jap.sso.JapMfa;
import com.fujieid.jap.sso.JapMfaService;
import com.hulk.dryad.common.component.R;
import com.hulk.dryad.common.constant.SecurityConstants;
import com.hulk.dryad.common.constant.enums.BEC;
import com.hulk.dryad.common.util.WebUtils;
import com.hulk.dryad.persistence.entity.SysUserModel;
import com.hulk.dryad.admin.service.SysUserService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Classname TotpAuthCodeFilter @Description 图形验证码过滤器 @Author hulk @Date 2020-07-07 23:02
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class TotpAuthCodeFilter extends OncePerRequestFilter implements Ordered {

	private static final String TOTP = "totp";

	private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

	private static final String UNAME = "username";

	private final SysUserService sysUserService;

	private final JapMfaService japMfaService;

	@Value("${dryad.totp.check.enabled:false}")
	private Boolean totpFlag;


	@Override
	protected void doFilterInternal(
			HttpServletRequest request, HttpServletResponse response, FilterChain chain)  throws IOException, ServletException{
		if (!totpFlag || !PATH_MATCHER.match(SecurityConstants.OAUTH_TOKEN_URL, request.getRequestURI())) {
			chain.doFilter(request, response);
			return;
		}
		// 验证一次性口令
		String username = request.getParameter(UNAME);
		String stotp = request.getParameter(TOTP);
		int totp = Integer.parseInt(!StringUtils.hasText(stotp) ? "0" : stotp);
		log.info("TotpAuthCodeFilter,username: [{}], totp: [{}]", username, totp);
		SysUserModel sysUser = sysUserService.getUserByName(username);
		if (sysUser == null) {
			WebUtils.renderJson(response, R.failed(BEC.E_2015));
			return;
		}
		JapMfa japMfa = new JapMfa(japMfaService);
		boolean verifyByUsernameResult = japMfa.verifyByUsername(username, totp);
		if (!verifyByUsernameResult) {
			WebUtils.renderJson(response, R.failed(BEC.E_2024));
			return;
		}
		chain.doFilter(request, response);
	}

	@Override
	public int getOrder() {
		return -200;
	}

}
